#pragma once
#ifndef VECTOR_H
#define VECTOR_H
#include <math.h>
#include <iostream>

class Vector{

public: 
  	float x,y,z;
	Vector(): x(0),y(0),z(1){}
	Vector(const Vector& p) : x(p.x), y(p.y), z(p.z) {}
	Vector(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
	
	Vector operator=(Vector& v){
		return Vector(x = v.x, y = v.y, z = v.z);
	}

	float length() const {
	    return (float) sqrt(x * x + y * y + z * z);
	}

    float magnitude() {
	    return x * x + y * y + z * z;
    }

    Vector normalize() {
		float s = 1.0 / (float) sqrt(x * x + y * y + z * z);
        return Vector(x *= s, y *= s, z *= s);
    }

    Vector invert (){
		x *=-1; y *=-1; z*=-1;
	    return Vector (x,y,z);
    }
};


//Vector Math
inline Vector operator+(const Vector& a, const Vector& b) {
  return Vector(a.x + b.x, a.y + b.y, a.z + b.z);
}
inline Vector operator+(const Vector& a, const float& b) {
  return Vector(a.x + b, a.y + b, a.z + b);
}
inline Vector operator-(const Vector& a, const Vector& b) {
  return Vector(a.x - b.x, a.y - b.y, a.z - b.z);
}
inline Vector operator*(float s, const Vector& v) {
  return Vector(s * v.x, s * v.y, s * v.z);
}
inline Vector operator*(const Vector& v, float s) {
  return Vector(s * v.x, s * v.y, s * v.z);
}
// dot product
inline float operator*(const Vector& a, const Vector& b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}
// cross product
inline Vector operator^(const Vector& a, const Vector& b) {
  return Vector(a.y * b.z - a.z * b.y,
                 a.z * b.x - a.x * b.z,
                 a.x * b.y - a.y * b.x);
}

#endif